home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / mach / sun4.md / machIntr.s < prev    next >
Text File  |  1992-12-18  |  6KB  |  203 lines

  1. /*
  2.  * machIntr.s --
  3.  *
  4.  *    Interrupts for sun4.
  5.  *
  6.  * Copyright 1989 Regents of the University of California
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. .seg    "data"
  17. .asciz    "$Header: /cdrom/src/kernel/Cvsroot/kernel/mach/sun4.md/machIntr.s,v 9.4 91/10/18 01:23:13 dlong Exp $ SPRITE (Berkeley)"
  18. .align    8
  19. .seg    "text"
  20.  
  21. #include "machConst.h"
  22. #include "machAsmDefs.h"
  23. #include "vmSunConst.h"
  24. #ifndef sun4c
  25. #include "devAddrs.h"
  26. #endif
  27.  
  28. .align    8
  29. .seg    "text"
  30.  
  31. /*
  32.  * ----------------------------------------------------------------------
  33.  *
  34.  * MachHandleInterrupt --
  35.  *
  36.  *    Handle an interrupt by calling the specific interrupt handler whose
  37.  *    address is given as our first (and only) argument.
  38.  *
  39.  *    MachHandleInterrupt(SpecificInterruptHandlerAddress)
  40.  *
  41.  * Results:
  42.  *    None.
  43.  *
  44.  * Side effects:
  45.  *    None.
  46.  *
  47.  * ----------------------------------------------------------------------
  48.  */
  49. .globl    MachHandleInterrupt
  50. MachHandleInterrupt:
  51.     /* set us at interrupt level - do this in trap handler?? */
  52.     sethi    %hi(_mach_AtInterruptLevel), %VOL_TEMP1
  53.     ld    [%VOL_TEMP1 + %lo(_mach_AtInterruptLevel)], %SAFE_TEMP
  54.     mov    1, %VOL_TEMP2
  55.     st    %VOL_TEMP2, [%VOL_TEMP1 + %lo(_mach_AtInterruptLevel)]
  56.  
  57.     and    %CUR_PSR_REG, MACH_PS_BIT, %VOL_TEMP1
  58.     sethi    %hi(_mach_KernelMode), %VOL_TEMP2
  59.                         /* 0 = user, !0 = kernel */
  60.     st    %VOL_TEMP1, [%VOL_TEMP2 + %lo(_mach_KernelMode)]
  61.  
  62.     /* Call into vector table using tbr */
  63.     and    %CUR_TBR_REG, MACH_TRAP_TYPE_MASK, %o0
  64.     sub    %o0, MACH_LEVEL0_INT, %o0    /* get interrupt level */
  65.     srl    %o0, 2, %VOL_TEMP1        /* convert to index */
  66.     sethi    %hi(_machInterruptArgs), %VOL_TEMP2
  67.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP2
  68.                         /* arg, if any */
  69.     ld    [%VOL_TEMP2 + %lo(_machInterruptArgs)], %o0
  70.     /*
  71.      * For now, this is the only way to get the interrupt pc to the
  72.      * profiler via the Timer_TimerService callback.  It's an implicit
  73.      * parameter.
  74.      */
  75.     mov    %CUR_PC_REG, %o1    /* pc as next arg. */
  76.     sethi    %hi(_machVectorTable), %VOL_TEMP2
  77.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP1
  78.     ld    [%VOL_TEMP1 + %lo(_machVectorTable)], %VOL_TEMP1
  79.     call    %VOL_TEMP1
  80.     nop
  81.  
  82.     sethi    %hi(_mach_AtInterruptLevel), %VOL_TEMP1
  83. #ifdef NOTDEF
  84.     tst    %SAFE_TEMP
  85.     bne    LeaveInterruptLevel
  86. #endif NOTDEF
  87.     nop
  88.     st    %g0, [%VOL_TEMP1 + %lo(_mach_AtInterruptLevel)]
  89. LeaveInterruptLevel:
  90.     /*
  91.      * Put a good return value into the return value register so that
  92.      * MachReturnFromTrap will be happy if we're returning to user mode.
  93.      */
  94.     mov    MACH_OK, %RETURN_VAL_REG
  95.  
  96.     set    _MachReturnFromTrap, %VOL_TEMP1
  97.     jmp    %VOL_TEMP1
  98.     nop
  99.  
  100.  
  101.  
  102. /*
  103.  * ----------------------------------------------------------------------
  104.  *
  105.  * MachVectoredInterrupt --
  106.  *
  107.  *    Handle an interrupt that requires getting an interrupt vector in
  108.  *    an interrupt acknowledge cycle.  The single argument to the routine is
  109.  *    the vme trap vector address to read.
  110.  *
  111.  * Results:
  112.  *    None.
  113.  *
  114.  * Side effects:
  115.  *    Handle the interrupt.
  116.  *
  117.  * ----------------------------------------------------------------------
  118.  */
  119. .globl    _MachVectoredInterrupt
  120. _MachVectoredInterrupt:
  121.     /* We need to return to a leaf routine, so we need to save a frame */
  122.     save    %sp, -MACH_FULL_STACK_FRAME, %sp
  123. .globl    _MachVectoredInterruptLoad
  124. _MachVectoredInterruptLoad:
  125.     lduba    [%i0] VMMACH_CONTROL_SPACE, %VOL_TEMP1    /* got vector */
  126.     sll    %VOL_TEMP1, 2, %VOL_TEMP1        /* convert to index */
  127.     sethi    %hi(_machInterruptArgs), %VOL_TEMP2
  128.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP2
  129.                             /* clientData arg */
  130.     ld    [%VOL_TEMP2 + %lo(_machInterruptArgs)], %o0
  131.     sethi    %hi(_machVectorTable), %VOL_TEMP2
  132.     add    %VOL_TEMP2, %VOL_TEMP1, %VOL_TEMP2
  133.     ld    [%VOL_TEMP2 + %lo(_machVectorTable)], %VOL_TEMP2
  134.     call    %VOL_TEMP2                /* %o0 is arg */
  135.     nop
  136.     ret
  137.     restore
  138.  
  139.  
  140.  
  141. /*
  142.  * ----------------------------------------------------------------------
  143.  *
  144.  * MachHandleLevel15Intr --
  145.  *
  146.  *    Handle a level 15 interrrupt.  This is a non-maskable memory error
  147.  *    interrupt, and we want to clear the condition so we report only
  148.  *    the first CE.  Then we'll jump to MachTrap and go into the debugger.
  149.  *
  150.  * Results:
  151.  *    None.
  152.  *
  153.  * Side effects:
  154.  *    We should go into the debugger.
  155.  *
  156.  * ----------------------------------------------------------------------
  157.  */
  158. .globl    MachHandleLevel15Intr
  159. MachHandleLevel15Intr:
  160.     /*
  161.      * Put the register values into global registers so we can see
  162.      * what they were easily when entering the debugger, since we'll
  163.      * mess up the locals before we get there.  We won't survive this
  164.      * error anyway, so we won't be needing the globals again.
  165.      */
  166. #ifdef sun4c
  167.     set    VMMACH_ASYNC_ERROR_REG, %VOL_TEMP1
  168.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g5
  169.  
  170.     set    VMMACH_ASYNC_ERROR_ADDR_REG, %VOL_TEMP1
  171.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g6
  172.  
  173.     /* I must clear these too to clear async error.  Very silly. */
  174.     set    VMMACH_SYNC_ERROR_REG, %VOL_TEMP1
  175.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g0
  176.  
  177.     set    VMMACH_SYNC_ERROR_ADDR_REG, %VOL_TEMP1
  178.     lda    [%VOL_TEMP1] VMMACH_CONTROL_SPACE, %g0
  179.  
  180.     /*
  181.      * To clear the interrupt condition, first write a 0 to the enable
  182.      * all interrupts bit, and then write a one again.
  183.      */
  184.     sethi    %hi(_machInterruptReg), %VOL_TEMP1
  185.     ld    [%VOL_TEMP1 + %lo(_machInterruptReg)], %VOL_TEMP1
  186.     ldub    [%VOL_TEMP1], %VOL_TEMP2
  187.     andn    %VOL_TEMP2, MACH_ENABLE_ALL_INTERRUPTS, %VOL_TEMP2
  188.     stb    %VOL_TEMP2, [%VOL_TEMP1]
  189.     or    %VOL_TEMP2, MACH_ENABLE_ALL_INTERRUPTS, %VOL_TEMP2
  190.     stb    %VOL_TEMP2, [%VOL_TEMP1]
  191. #else
  192.     set    VMMACH_ADDR_CONTROL_REG, %VOL_TEMP1
  193.     ld    [%VOL_TEMP1], %g5
  194.  
  195.     and    %VOL_TEMP2, ~VMMACH_ENABLE_MEM_ERROR_BIT, %VOL_TEMP2
  196.     st    %VOL_TEMP2, [%VOL_TEMP1]
  197.     set    VMMACH_ADDR_ERROR_REG, %VOL_TEMP1
  198.     ld    [%VOL_TEMP1], %g6
  199. #endif
  200.     set    _MachTrap, %VOL_TEMP1
  201.     jmp    %VOL_TEMP1
  202.     nop
  203.